package com.forehope.portal.job;

import com.actionsoft.bpms.bo.engine.BO;
import com.actionsoft.bpms.bpmn.engine.model.def.ProcessDefinition;
import com.actionsoft.bpms.bpmn.engine.model.run.delegate.ProcessInstance;
import com.actionsoft.bpms.bpmn.engine.model.run.delegate.TaskInstance;
import com.actionsoft.bpms.org.cache.DepartmentCache;
import com.actionsoft.bpms.org.model.DepartmentModel;
import com.actionsoft.bpms.org.model.UserModel;
import com.actionsoft.bpms.schedule.IJob;
import com.actionsoft.sdk.local.SDK;
import com.alibaba.fastjson.JSONObject;
import com.forehope.portal.aslpUtil.MailUtil;
import com.forehope.portal.enumUtil.PositionData;
import jodd.util.StringUtil;
import org.owasp.esapi.User;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

import static com.forehope.portal.aslpUtil.MailUtil.sendMailToUser;

public class CbJob implements IJob {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        /**
         * 获取权限
         */
        //特殊处理借料申请单-申请人节点，超过31天不发送通知的问题
        List<TaskInstance> taskList1 = SDK.getTaskQueryAPI().userTask().activeTask().processDefId("obj_45144161ffa74093af553adab7cf5a97").activityDefId("obj_cab6c81a40100001892910f08b64e180").list();
        for (TaskInstance taskInstance : taskList1) {
            Timestamp beginTime = taskInstance.getBeginTime();
            LocalDateTime timestampDateTime = beginTime.toLocalDateTime();
            LocalDateTime newDateTime = timestampDateTime.plus(31, ChronoUnit.DAYS);
            // 计算两个时间点之间的时间差
            Timestamp newTimestamp = Timestamp.valueOf(newDateTime);
            // 判断是否超过31天
            SDK.getTaskAPI().setDueTime(taskInstance.getId(), newTimestamp);
        }


        /**
         * 获取所有待办数据
         */
        List<TaskInstance> taskList = SDK.getTaskQueryAPI().userTask().activeTask().addQuery("DUETIME IS NOT NULL", null).list();


        /**
         * 分组数据
         */
        Map<String, List<TaskInstance>> totalList = taskList.stream().collect(Collectors.groupingBy(TaskInstance::getTarget));
        Map<String, List<TaskInstance>> one = new HashMap<>();
        Map<String, List<TaskInstance>> three = new HashMap<>();
        Map<String, List<TaskInstance>> seven = new HashMap<>();
        for (String target : totalList.keySet()) {
            if (StringUtil.isEmpty(target)) {
                continue;
            }
            List<TaskInstance> oneList = new ArrayList<>();
            List<TaskInstance> threeList = new ArrayList<>();
            List<TaskInstance> sevenList = new ArrayList<>();
            //获取此人所有已超期流程
            List<TaskInstance> list = totalList.get(target);

            for (TaskInstance taskInstance : list) {
                //当前时间
                Timestamp nowTime = new Timestamp(System.currentTimeMillis());
                //当前时间
                Timestamp dueTime = taskInstance.getDueTime();
                /**
                 * 判断超时时间
                 */
                long result = getTime(dueTime, nowTime);
                if (result >= 1) {
                    oneList.add(taskInstance);
                }
                if (result >= 3) {
                    threeList.add(taskInstance);
                }
                if (result >= 7) {
                    sevenList.add(taskInstance);
                }
            }
            one.put(target, oneList);
            three.put(target, threeList);
            seven.put(target, sevenList);
        }

        //发送邮件
        sendEmailToDo(one);
        sendEmailToReport(three);
        sendEmailToReport2(seven);

    }

    public void sendEmailToDo(Map<String, List<TaskInstance>> totalList) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        String time = simpleDateFormat.format(date);
        String subject = "【" + time + "BPM流程超期提醒】";
        for (String target : totalList.keySet()) {
            UserModel userModel = SDK.getORGAPI().getUser(target);
            if (checkUser(userModel)) {
                //账号有效且非厂级
                //发送此人待办邮件
                List<TaskInstance> list = totalList.get(target);
                if (list == null || list.size() == 0) {
                    continue;
                }
                List<TaskInstance> newList = list.stream().sorted(Comparator.comparing(TaskInstance::getBeginTime)).collect(Collectors.toList());
                String result = "<tbody>";
                for (TaskInstance taskInstance : newList) {
                    result = result + getHtml(taskInstance);
                }
                result = result + "</tbody>";
                //内容
                String resulttemplate = MailUtil.getMaiTemplate("dc9c8137-3352-4985-87b1-82d20e15b83f");
                String content = resulttemplate.replace("<tbody></tbody>", result).replace("TARGET", userModel.getUserName());
                sendMailToUser(subject, content, userModel.getEmail(), "");
            }
        }

    }

    public void sendEmailToReport(Map<String, List<TaskInstance>> totalList) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        String time = simpleDateFormat.format(date);
        String subject = "【" + time + "BPM流程超期提醒】";

        Map<String, List<TaskInstance>> reportList = new HashMap<>();


        /**
         * 清洗数据
         */
        for (String target : totalList.keySet()) {
            //获取代办人汇报人
            UserModel userModel = SDK.getORGAPI().getUser(target);
            if (userModel != null) {
                String report = userModel.getReportTo();
                //判断是否已经赛过数据了
                List<TaskInstance> isHas = reportList.get(report);
                if (isHas == null) {
                    isHas = new ArrayList<>();
                }
                UserModel reportModel = SDK.getORGAPI().getUser(report);
                if (checkUser(reportModel)) {
                    isHas.addAll(totalList.get(target));
                }
                reportList.put(report, isHas);
            }
        }


        for (String report : reportList.keySet()) {
            UserModel userModel = SDK.getORGAPI().getUser(report);
            //账号有效且非厂级
            //发送此人待办邮件
            List<TaskInstance> list = reportList.get(report);
            if (list == null || list.size() == 0) {
                continue;
            }
            List<TaskInstance> newList = list.stream().sorted(Comparator.comparing(TaskInstance::getBeginTime)).collect(Collectors.toList());
            String result = "<tbody>";
            for (TaskInstance taskInstance : newList) {
                result = result + getHtml(taskInstance);
            }
            result = result + "</tbody>";
            //内容
            String resulttemplate = MailUtil.getMaiTemplate("8e9bd588-4760-4145-86e0-145e51a52b75");
            String content = resulttemplate.replace("<tbody></tbody>", result).replace("TARGET", userModel.getUserName());
            sendMailToUser(subject, content, userModel.getEmail(), "");
        }


    }

    public void sendEmailToReport2(Map<String, List<TaskInstance>> totalList) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        String time = simpleDateFormat.format(date);
        String subject = "【" + time + "BPM流程超期提醒】";

        Map<String, List<TaskInstance>> report2List = new HashMap<>();


        /**
         * 清洗数据
         */
        for (String target : totalList.keySet()) {
            //获取代办人汇报人
            UserModel userModel = SDK.getORGAPI().getUser(target);
            if (userModel == null) {
                continue;
            }
            String report = userModel.getReportTo();
            if (target.equals(report)) {
                continue;
            }
            UserModel reportModel = SDK.getORGAPI().getUser(report);
            String report2 = "";
            if (reportModel != null && !reportModel.isClosed()) {
                report2 = reportModel.getReportTo();
            }
            if (StringUtil.isNotEmpty(report2)) {
                //判断是否已经赛过数据了
                List<TaskInstance> isHas = report2List.get(report2);
                if (isHas == null) {
                    isHas = new ArrayList<>();
                }
                if (checkUser(SDK.getORGAPI().getUser(report2))) {
                    isHas.addAll(totalList.get(target));
                }
                report2List.put(report2, isHas);
            } else {
                continue;
            }

        }
        for (String report : report2List.keySet()) {
            UserModel userModel = SDK.getORGAPI().getUser(report);
            //账号有效且非厂级
            //发送此人待办邮件
            List<TaskInstance> list = report2List.get(report);
            if (list == null || list.size() == 0) {
                continue;
            }
            List<TaskInstance> newList = list.stream().sorted(Comparator.comparing(TaskInstance::getBeginTime)).collect(Collectors.toList());
            String result = "<tbody>";
            for (TaskInstance taskInstance : newList) {
                result = result + getHtml(taskInstance);
            }
            result = result + "</tbody>";
            //内容
            String resulttemplate = MailUtil.getMaiTemplate("8e9bd588-4760-4145-86e0-145e51a52b75");
            String content = resulttemplate.replace("<tbody></tbody>", result).replace("TARGET", userModel.getUserName());
            sendMailToUser(subject, content, userModel.getEmail(), "");
        }

    }


    public boolean checkUser(UserModel userModel) {
        if (userModel != null && checkLevel(userModel.getUID()) && !userModel.isClosed()) {
            return true;
        } else {
            return false;
        }
    }

    public long getTime(Timestamp beginTime, Timestamp operaTime) {
        // 计算时间差（以毫秒为单位）
        long milliseconds = operaTime.getTime() - beginTime.getTime();
        // 将毫秒转换为天、小时、分钟和秒
        long seconds = milliseconds / 1000;
        long fen = seconds / 60;
        long days = seconds / (24 * 3600);

        return days;
    }

    public Map<String, Object> getTime1(Timestamp beginTime, Timestamp operaTime) {
        Map<String, Object> map = new HashMap<>();
        // 计算时间差（以毫秒为单位）
        long milliseconds = operaTime.getTime() - beginTime.getTime();
        // 将毫秒转换为天、小时、分钟和秒
        long seconds = milliseconds / 1000;
        long days = seconds / (24 * 3600);
        seconds = seconds % (24 * 3600);
        long hours = seconds / 3600;
        seconds = seconds % 3600;
        long minutes = seconds / 60;
        String result = "";
        if (days > 0) {
            result = result + days + "天";
        }
        if (hours > 0) {
            result = result + hours + "小时";
        }
        if (minutes > 0 && days == 0) {
            result = result + minutes + "分";
        }
        map.put("days", minutes);
        map.put("log", result);
        return map;
    }

    public boolean checkLevel(String uid) {
        UserModel userModel = SDK.getORGAPI().getUser(uid);
        String positionLayer = userModel.getPositionLayer();
        /**
         * 厂以下
         */
        PositionData positionData = new PositionData();

        String[] MData = positionData.M;
        String[] OData = positionData.O;
        String[] PData = positionData.P;
        String[] SData = positionData.S;
        String[] TData = positionData.T;
        String[] WData = positionData.W;
        for (String position : MData) {
            if (positionLayer.equals(position)) {
                return true;
            }
        }
        for (String position : OData) {
            if (positionLayer.equals(position)) {
                return true;
            }
        }
        for (String position : PData) {
            if (positionLayer.equals(position)) {
                return true;
            }
        }
        for (String position : SData) {
            if (positionLayer.equals(position)) {
                return true;
            }
        }
        for (String position : TData) {
            if (positionLayer.equals(position)) {
                return true;
            }
        }
        for (String position : WData) {
            if (positionLayer.equals(position)) {
                return true;
            }
        }
        return false;
    }


    public String getHtml(TaskInstance taskInstance) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        //工号
        String target = taskInstance.getTarget();
        //代办人
        UserModel targetModel = SDK.getORGAPI().getUser(taskInstance.getTarget());
        String name = targetModel.getUserName();
        //当前人所在部门
        String departmentId = targetModel.getDepartmentId();
        DepartmentModel targetDepartment = SDK.getORGAPI().getDepartmentById(departmentId);
        //当前人所在大部门
        String pathName = targetDepartment.getPathNameOfCache();
        String allDepartment = pathName.split("/")[0];
        //发起人
        String processInstId = taskInstance.getProcessInstId();
        ProcessInstance processInstance = SDK.getProcessAPI().getInstanceById(processInstId);
        String createUser = processInstance.getCreateUser();
        String createUserName = "";
        if (StringUtil.isNotEmpty(createUser)) {
            UserModel userModel = SDK.getORGAPI().getUser(createUser);
            if (userModel != null && !userModel.isClosed()) {
                createUserName = userModel.getUserName();
            } else {
                createUserName = createUser;
            }
        } else {
            createUserName = "人员异常";
        }

        //节点权限
        taskInstance.getActivityDefId();
        //待办事项
        String title = processInstance.getTitle();
        //流程名称
        String processDefId = processInstance.getProcessDefId();
        ProcessDefinition processDefinition = SDK.getRepositoryAPI().getProcessDefinition(processDefId);
        String processDefType = "";
        if (processDefinition != null) {
            processDefType = processDefinition.getName();
        }
        //流程接收时间
        Timestamp timestamp = taskInstance.getBeginTime();
        Date startDate = new Date(timestamp.getTime());
        String startTime = simpleDateFormat.format(startDate);
        //待办时长
        //当前时间
        Timestamp nowTime = new Timestamp(System.currentTimeMillis());
        //当前时间
        Timestamp dueTime = taskInstance.getDueTime();
//        Map<String, Object> map = getTime1(dueTime, nowTime);
//        String time =map.get("log").toString();
        long day = getTime(dueTime, nowTime);
        String time = day + "天";

        String htmlModel =
                "<tr>" +
                        "<td style=\"border-style: solid;border-width: 1px;border-color:#808080;text-align:center\">" + target + "</td>" +
                        "<td style=\"border-style: solid;border-width: 1px;border-color:#808080;text-align:center\">" + name + "</td>" +
                        "<td style=\"border-style: solid;border-width: 1px;border-color:#808080;text-align:center\">" + targetDepartment.getName() + "</td>" +
                        "<td style=\"border-style: solid;border-width: 1px;border-color:#808080;text-align:center\">" + allDepartment + "</td>" +
                        "<td style=\"border-style: solid;border-width: 1px;border-color:#808080;text-align:center\">" + createUserName + "</td>" +
//                        "<td style=\"border-style: solid;border-width: 1px;\">" + "//" + "</td>" +
                        "<td style=\"border-style: solid;border-width: 1px;border-color:#808080;text-align:left\">" + title + "</td>" +
                        "<td style=\"border-style: solid;border-width: 1px;border-color:#808080;text-align:center\">" + processDefType + "</td>" +
                        "<td style=\"border-style: solid;border-width: 1px;border-color:#808080;text-align:center\">" + startTime + "</td>" +
                        "<td style=\"border-style: solid;border-width: 1px;border-color:#808080;text-align:center\">" + time + "</td>" +
                        "</tr>";
        return htmlModel;
    }
}
